<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>虚拟列表 - 固定高度</title>
  <style>
    .virtual-list-container {
      width: 300px;
      height: 500px;
      margin: 20px auto;
      border: 1px solid #ddd;
      overflow-y: auto;
      position: relative;
    }
    
    .virtual-list-scroller {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
    }
    
    .virtual-list-item {
      height: 50px;
      line-height: 50px;
      border-bottom: 1px solid #eee;
      padding: 0 10px;
      box-sizing: border-box;
    }
    
    .virtual-list-item:hover {
      background-color: #f5f5f5;
    }
  </style>
</head>
<body>
  <div class="virtual-list-container" id="listContainer">
    <div class="virtual-list-scroller" id="listScroller"></div>
  </div>

  <script>
    // 配置参数
    const config = {
      itemHeight: 50,      // 每项固定高度
      itemCount: 10000,    // 总项数
      bufferSize: 5,       // 缓冲区大小
    };
    
    // 获取DOM元素
    const container = document.getElementById('listContainer');
    const scroller = document.getElementById('listScroller');
    
    // 初始化虚拟列表
    function initVirtualList() {
      // 设置滚动区域总高度
      scroller.style.height = `${config.itemHeight * config.itemCount}px`;
      
      // 监听滚动事件
      container.addEventListener('scroll', handleScroll);
      
      // 初始渲染
      renderItems();
    }
    
    // 处理滚动事件
    function handleScroll() {
      renderItems();
    }
    
    // 渲染可视区域的项目
    function renderItems() {
      // 计算可视区域的起始和结束索引
      const scrollTop = container.scrollTop;
      const visibleCount = Math.ceil(container.clientHeight / config.itemHeight);
      const startIndex = Math.max(0, Math.floor(scrollTop / config.itemHeight) - config.bufferSize);
      const endIndex = Math.min(
        startIndex + visibleCount + config.bufferSize * 2,
        config.itemCount - 1
      );
      
      // 计算偏移量
      const offset = startIndex * config.itemHeight;
      
      // 生成当前需要渲染的项目
      let itemsHTML = '';
      for (let i = startIndex; i <= endIndex; i++) {
        itemsHTML += `
          <div class="virtual-list-item" data-index="${i}">
            项目 ${i + 1} / ${config.itemCount}
          </div>
        `;
      }
      
      // 更新DOM
      scroller.innerHTML = itemsHTML;
      scroller.style.transform = `translateY(${offset}px)`;
    }
    
    // 初始化
    initVirtualList();
  </script>
</body>
</html>